home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / xmesa2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-03  |  60.6 KB  |  2,256 lines

  1. /* $Id: xmesa2.c,v 1.9 1995/11/30 00:52:30 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Log: xmesa2.c,v $
  26.  * Revision 1.9  1995/11/30  00:52:30  brianp
  27.  * fixed a few type warnings for Sun compiler
  28.  *
  29.  * Revision 1.8  1995/11/30  00:21:23  brianp
  30.  * added new PF_GRAYSCALE mode
  31.  *
  32.  * Revision 1.7  1995/11/03  17:41:48  brianp
  33.  * removed unused vars, fixed code for C++ compilation
  34.  *
  35.  * Revision 1.6  1995/11/01  23:19:21  brianp
  36.  * fixed bugs in write_span_DITHER_pixmap and write_span_LOOKUP_pixmap
  37.  *
  38.  * Revision 1.5  1995/10/30  15:33:49  brianp
  39.  * added mask argument to read_[color|index]_pixels functions
  40.  *
  41.  * Revision 1.4  1995/10/30  15:13:53  brianp
  42.  * replaced Current variable with XMesa
  43.  * moved accelerated point, line, polygon functions to xmesa3.c
  44.  *
  45.  * Revision 1.3  1995/10/22  20:28:34  brianp
  46.  * removed some dead code
  47.  *
  48.  * Revision 1.2  1995/10/19  15:54:06  brianp
  49.  * changed clear_color and set_color arguments to GLubytes
  50.  *
  51.  * Revision 1.1  1995/10/17  21:37:09  brianp
  52.  * Initial revision
  53.  *
  54.  */
  55.  
  56.  
  57.  
  58. /*
  59.  * Mesa/X11 interface, part 2.
  60.  *
  61.  * This file contains the implementations of all the DD.* functions.
  62.  */
  63.  
  64.  
  65.  
  66. #include <stdio.h>
  67. #include <stdlib.h>
  68. #include <string.h>
  69. #include <X11/Xlib.h>
  70. #include "dd.h"
  71. #include "macros.h"
  72. #include "xmesaP.h"
  73. #include "GL/xmesa.h"
  74.  
  75. /*
  76.  * Abort with an error message.
  77.  */
  78. static void die( char *s )
  79. {
  80.    fprintf( stderr, "%s\n", s );
  81.    abort();
  82. }
  83.  
  84.  
  85.  
  86. /*
  87.  * Read a pixel from an X drawable.
  88.  */
  89. static unsigned long read_pixel( Display *dpy, Drawable d, int x, int y )
  90. {
  91.    XImage *pixel;
  92.    unsigned long p;
  93.  
  94.    pixel = XGetImage( dpy, d, x, y, 1, 1, AllPlanes, ZPixmap );
  95.    if (pixel) {
  96.       p = XGetPixel( pixel, 0, 0 );
  97.       XDestroyImage( pixel );
  98.    }
  99.    else {
  100.       p = 0;
  101.    }
  102.  
  103.    return p;
  104. }
  105.  
  106.  
  107.  
  108.  
  109. /*
  110.  * Return the size (width,height,depth) of the current color buffer.
  111.  * This function should be called by the glViewport function because
  112.  * glViewport is often called when the window gets resized.  We need to
  113.  * update some X/Mesa stuff when that happens.
  114.  * Output:  width - width of buffer in pixels.
  115.  *          height - height of buffer in pixels.
  116.  *          depth - In Color Index mode, return bits/pixel
  117.  *                - In RGBA mode, return bits/component
  118.  */
  119. static void buffer_size( GLuint *width, GLuint *height, GLuint *depth )
  120. {
  121.    Window root;
  122.    int winx, winy;
  123.    unsigned int winwidth, winheight;
  124.    unsigned int bw, d;
  125.  
  126.    XGetGeometry( XMesa->display, XMesa->frontbuffer, &root,
  127.          &winx, &winy, &winwidth, &winheight, &bw, &d );
  128.  
  129.    *width = winwidth;
  130.    *height = winheight;
  131.    *depth = XMesa->depth;
  132.  
  133.    if (winwidth!=XMesa->width || winheight!=XMesa->height) {
  134.       XMesa->width = winwidth;
  135.       XMesa->height = winheight;
  136.       xmesa_alloc_back_buffer( XMesa );
  137.    }
  138. }
  139.  
  140.  
  141. static void finish( void )
  142. {
  143.    if (XMesa) {
  144.       XSync( XMesa->display, False );
  145.    }
  146. }
  147.  
  148.  
  149. static void flush( void )
  150. {
  151.    if (XMesa) {
  152.       XFlush( XMesa->display );
  153.    }
  154. }
  155.  
  156.  
  157.  
  158. static GLboolean set_buffer( GLenum mode )
  159. {
  160.    if (mode==GL_FRONT) {
  161.       /* read/write front buffer */
  162.       XMesa->buffer = XMesa->frontbuffer;
  163.       xmesa_setup_DD_pointers();
  164.       return GL_TRUE;
  165.    }
  166.    else if (mode==GL_BACK && XMesa->db_state) {
  167.       /* read/write back buffer */
  168.       if (XMesa->backpixmap) {
  169.          XMesa->buffer = XMesa->backpixmap;
  170.       }
  171.       else if (XMesa->backimage) {
  172.          XMesa->buffer = None;
  173.       }
  174.       else {
  175.          /* just in case, probably a serious error? */
  176.          XMesa->buffer = XMesa->frontbuffer;
  177.       }
  178.       xmesa_setup_DD_pointers();
  179.       return GL_TRUE;
  180.    }
  181.    else {
  182.       return GL_FALSE;
  183.    }
  184. }
  185.  
  186.  
  187.  
  188. static void clear_index( GLuint index )
  189. {
  190.    XMesa->clearpixel = (unsigned long) index;
  191.    XSetForeground( XMesa->display, XMesa->cleargc, (unsigned long) index );
  192. }
  193.  
  194.  
  195. static void clear_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  196. {
  197.    unsigned long p;
  198.    switch (XMesa->pixelformat) {
  199.       case PF_INDEX:
  200.          return;
  201.       case PF_TRUECOLOR:
  202.      p = PACK_RGB( r, g, b );
  203.      break;
  204.       case PF_8A8B8G8R:
  205.          p =  (a << 24) | (b << 16) | (g << 8) | r;
  206.      break;
  207.       case PF_DITHER:
  208.      p = DITHER_8BIT( 0, 0, r, g, b );
  209.      break;
  210.       case PF_1BIT:
  211.      p = (r+g+b) > 382U;
  212.      break;
  213.       case PF_HPCR:
  214.          p = DITHER_HPCR(1, 1, r, g, b);
  215.          break;
  216.       case PF_LOOKUP:
  217.          p = LOOKUP( r, g, b );
  218.          break;
  219.       case PF_GRAYSCALE:
  220.          p = GRAY_RGB( r, g, b );
  221.          break;
  222.       default:
  223.      abort();
  224.    }
  225.    XMesa->clearpixel = p;
  226.    XSetForeground( XMesa->display, XMesa->cleargc, p );
  227. }
  228.  
  229.  
  230. /* Set current color index */
  231. static void set_index( GLuint index )
  232. {
  233.    unsigned long p = (unsigned long) index;
  234.    XMesa->pixel = p;
  235.    XSetForeground( XMesa->display, XMesa->gc1, p );
  236. }
  237.  
  238.  
  239. /* Set current drawing color */
  240. static void set_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  241. {
  242.    register unsigned long p;
  243.    switch (XMesa->pixelformat) {
  244.       case PF_INDEX:
  245.          return;
  246.       case PF_TRUECOLOR:
  247.      p = PACK_RGB( r, g, b );
  248.      break;
  249.       case PF_8A8B8G8R:
  250.          p = (a << 24) | (b << 16) | (g << 8) | r;
  251.      break;
  252.       case PF_DITHER:
  253.          XMesa->red = r;
  254.          XMesa->green = g;
  255.          XMesa->blue = b;
  256.      p = DITHER_8BIT( 0, 0, r, g, b );
  257.      break;
  258.       case PF_1BIT:
  259.      p = (r+g+b) > 382U;
  260.      break;
  261.       case PF_HPCR:
  262.          XMesa->red = r;
  263.          XMesa->green = g;
  264.          XMesa->blue = b;
  265.          p = DITHER_HPCR(1, 1, r, g, b);
  266.          break;
  267.       case PF_LOOKUP:
  268.          p = LOOKUP( r, g, b );
  269.          break;
  270.       case PF_GRAYSCALE:
  271.          p = GRAY_RGB( r, g, b );
  272.          break;
  273.       default:
  274.      abort();
  275.    }
  276.    XMesa->pixel = p;
  277.    XSetForeground( XMesa->display, XMesa->gc1, p );
  278. }
  279.  
  280.  
  281.  
  282. /* Set index mask ala glIndexMask */
  283. static GLboolean index_mask( GLuint mask )
  284. {
  285.    if (XMesa->buffer==XIMAGE) {
  286.       return GL_FALSE;
  287.    }
  288.    else {
  289.       unsigned long m;
  290.       if (mask==0xffffffff) {
  291.          m = AllPlanes;
  292.       }
  293.       else {
  294.          m = (unsigned long) mask;
  295.       }
  296.       XSetPlaneMask( XMesa->display, XMesa->gc1, m );
  297.       XSetPlaneMask( XMesa->display, XMesa->gc2, m );
  298.       XSetPlaneMask( XMesa->display, XMesa->cleargc, m );
  299.       return GL_TRUE;
  300.    }
  301. }
  302.  
  303.  
  304. /* Implements glColorMask() */
  305. static GLboolean color_mask( GLboolean rmask, GLboolean gmask,
  306.                              GLboolean bmask, GLboolean amask )
  307. {
  308. #if defined(__cplusplus) || defined(c_plusplus)
  309.    if (XMesa->buffer!=XIMAGE && (   XMesa->visual->c_class==TrueColor
  310.                                    || XMesa->visual->c_class==DirectColor)) {
  311. #else
  312.    if (XMesa->buffer!=XIMAGE && (   XMesa->visual->class==TrueColor
  313.                                    || XMesa->visual->class==DirectColor)) {
  314. #endif
  315.       unsigned long m;
  316.       if (rmask && gmask && bmask) {
  317.          m = AllPlanes;
  318.       }
  319.       else {
  320.          m = 0;
  321.          if (rmask)   m |= XMesa->visual->red_mask;
  322.          if (gmask)   m |= XMesa->visual->green_mask;
  323.          if (bmask)   m |= XMesa->visual->blue_mask;
  324.       }
  325.       XSetPlaneMask( XMesa->display, XMesa->gc1, m );
  326.       XSetPlaneMask( XMesa->display, XMesa->gc2, m );
  327.       XSetPlaneMask( XMesa->display, XMesa->cleargc, m );
  328.       return GL_TRUE;
  329.    }
  330.    else {
  331.       return GL_FALSE;
  332.    }
  333. }
  334.  
  335.  
  336. /*
  337.  * Set the pixel logic operation.  Return GL_TRUE if the device driver
  338.  * can perform the operation, otherwise return GL_FALSE.  GL_COPY _must_
  339.  * be operational, obviously.
  340.  */
  341. static GLboolean logicop( GLenum op )
  342. {
  343.    int func;
  344.    if (!XMesa)  return GL_FALSE;
  345.    if ((XMesa->buffer==XIMAGE) && op!=GL_COPY) {
  346.       /* X can't do logic ops in Ximages, except for GL_COPY */
  347.       return GL_FALSE;
  348.    }
  349.    switch (op) {
  350.       case GL_CLEAR:        func = GXclear;        break;
  351.       case GL_SET:        func = GXset;        break;
  352.       case GL_COPY:        func = GXcopy;        break;
  353.       case GL_COPY_INVERTED:    func = GXcopyInverted;    break;
  354.       case GL_NOOP:        func = GXnoop;        break;
  355.       case GL_INVERT:        func = GXinvert;    break;
  356.       case GL_AND:        func = GXand;        break;
  357.       case GL_NAND:        func = GXnand;        break;
  358.       case GL_OR:        func = GXor;        break;
  359.       case GL_NOR:        func = GXnor;        break;
  360.       case GL_XOR:        func = GXxor;        break;
  361.       case GL_EQUIV:        func = GXequiv;        break;
  362.       case GL_AND_REVERSE:    func = GXandReverse;    break;
  363.       case GL_AND_INVERTED:    func = GXandInverted;    break;
  364.       case GL_OR_REVERSE:    func = GXorReverse;    break;
  365.       case GL_OR_INVERTED:    func = GXorInverted;    break;
  366.       default:  return GL_FALSE;
  367.    }
  368.    XSetFunction( XMesa->display, XMesa->gc1, func );
  369.    XSetFunction( XMesa->display, XMesa->gc2, func );
  370.    return GL_TRUE;
  371. }
  372.  
  373.  
  374. /*
  375.  * Enable/disable dithering
  376.  */
  377. static void dither( GLboolean enable )
  378. {
  379.    if (enable) {
  380.       XMesa->pixelformat = XMesa->dithered_pf;
  381.    }
  382.    else {
  383.       XMesa->pixelformat = XMesa->undithered_pf;
  384.    }
  385.    xmesa_setup_DD_pointers();
  386. }
  387.  
  388.  
  389.  
  390. /**********************************************************************/
  391. /*** glClear implementations                                        ***/
  392. /**********************************************************************/
  393.  
  394. static void clear_pixmap( GLboolean all,
  395.                           GLint x, GLint y, GLint width, GLint height )
  396. {
  397.    if (all) {
  398.       XFillRectangle( XMesa->display, XMesa->buffer,
  399.                       XMesa->cleargc,
  400.                       0, 0, XMesa->width+1, XMesa->height+1 );
  401.    }
  402.    else {
  403.       XFillRectangle( XMesa->display, XMesa->buffer,
  404.                       XMesa->cleargc,
  405.                       x, XMesa->height - y - height, width, height );
  406.    }
  407. }
  408.  
  409. static void clear_8bit_ximage( GLboolean all,
  410.                                GLint x, GLint y, GLint width, GLint height )
  411. {
  412.    if (all) {
  413.       size_t n;
  414.       n = XMesa->backimage->bytes_per_line*XMesa->backimage->height;
  415.       MEMSET( XMesa->backimage->data, XMesa->clearpixel, n );
  416.    }
  417.    else {
  418.       /* TODO: optimize this */
  419.       register int i, j;
  420.       y = FLIP(y);
  421.       for (j=0;j<height;j++) {
  422.          for (i=0;i<width;i++) {
  423.             XPutPixel( XMesa->backimage, x+i, y-j, XMesa->clearpixel );
  424.          }
  425.       }
  426.    }
  427. }
  428.  
  429. static void clear_16bit_ximage( GLboolean all,
  430.                                 GLint x, GLint y, GLint width, GLint height )
  431. {
  432.    if (all) {
  433.       register GLuint n;
  434.       register GLushort *ptr, pixel;
  435.       n = XMesa->backimage->bytes_per_line/2 * XMesa->height;
  436.       ptr = (GLushort *) XMesa->backimage->data;
  437.       pixel = (GLushort) XMesa->clearpixel;
  438.       do {
  439.          *ptr++ = pixel;
  440.          n--;
  441.       } while (n!=0);
  442.    }
  443.    else {
  444.       /* TODO: optimize this */
  445.       register int i, j;
  446.       y = FLIP(y);
  447.       for (j=0;j<height;j++) {
  448.          for (i=0;i<width;i++) {
  449.             XPutPixel( XMesa->backimage, x+i, y-j, XMesa->clearpixel );
  450.          }
  451.       }
  452.    }
  453. }
  454.  
  455. static void clear_32bit_ximage( GLboolean all,
  456.                                 GLint x, GLint y, GLint width, GLint height )
  457. {
  458.    if (all) {
  459.       register GLuint n, *ptr, pixel;
  460.       n = XMesa->width * XMesa->height;
  461.       ptr = (GLuint *) XMesa->backimage->data;
  462.       pixel = (GLuint) XMesa->clearpixel;
  463.       do {
  464.          *ptr++ = pixel;
  465.          n--;
  466.       } while (n!=0);
  467.    }
  468.    else {
  469.       /* TODO: optimize this */
  470.       register int i, j;
  471.       y = FLIP(y);
  472.       for (j=0;j<height;j++) {
  473.          for (i=0;i<width;i++) {
  474.             XPutPixel( XMesa->backimage, x+i, y-j, XMesa->clearpixel );
  475.          }
  476.       }
  477.    }
  478. }
  479.  
  480. static void clear_nbit_ximage( GLboolean all,
  481.                                GLint x, GLint y, GLint width, GLint height )
  482. {
  483.    if (all) {
  484.       register int i, j;
  485.       for (j=0;j<XMesa->height;j++) {
  486.          for (i=0;i<XMesa->width;i++) {
  487.             XPutPixel( XMesa->backimage, i, j, XMesa->clearpixel );
  488.          }
  489.       }
  490.    }
  491.    else {
  492.       /* TODO: optimize this */
  493.       register int i, j;
  494.       y = FLIP(y);
  495.       for (j=0;j<height;j++) {
  496.          for (i=0;i<width;i++) {
  497.             XPutPixel( XMesa->backimage, x+i, y-j, XMesa->clearpixel );
  498.          }
  499.       }
  500.    }
  501. }
  502.  
  503.  
  504.  
  505.  
  506. /*
  507.  * The Mesa library needs to be able to draw pixels in a number of ways:
  508.  *   1. RGB vs Color Index
  509.  *   2. as horizontal spans (polygons, images) vs random locations (points,
  510.  *      lines)
  511.  *   3. different color per-pixel or same color for all pixels
  512.  *
  513.  * Furthermore, the X driver needs to support rendering to 3 possible
  514.  * "buffers", usually one, but sometimes two at a time:
  515.  *   1. The front buffer as an X window
  516.  *   2. The back buffer as a Pixmap
  517.  *   3. The back buffer as an XImage
  518.  *
  519.  * Finally, if the back buffer is an XImage, we can avoid using XPutPixel and
  520.  * optimize common cases such as 24-bit and 8-bit modes.
  521.  *
  522.  * By multiplication, there's at least 48 possible combinations of the above.
  523.  *
  524.  * Below are implementations of the most commonly used combinations.  They are
  525.  * accessed through function pointers which get initialized here and are used
  526.  * directly from the Mesa library.  The 8 function pointers directly correspond
  527.  * to the first 3 cases listed above.
  528.  *
  529.  *
  530.  * The function naming convention is:
  531.  *
  532.  *   write_[span|pixels]_[mono]_[format]_[pixmap|ximage]
  533.  *
  534.  * New functions optimized for specific cases can be added without too much
  535.  * trouble.  An example might be the 24-bit TrueColor mode 8A8R8G8B which is
  536.  * found on IBM RS/6000 X servers.
  537.  */
  538.  
  539.  
  540.  
  541.  
  542. /**********************************************************************/
  543. /*** Write COLOR SPAN functions                                     ***/
  544. /**********************************************************************/
  545.  
  546.  
  547. #define COLOR_SPAN_ARGS    GLuint n, GLint x, GLint y,            \
  548.             const GLubyte red[], const GLubyte green[],    \
  549.             const GLubyte blue[], const GLubyte alpha[],    \
  550.             const GLubyte mask[]
  551.  
  552. /* NOTE: if mask==NULL, draw all pixels */
  553.  
  554.  
  555. /*
  556.  * Write a span of PF_TRUECOLOR pixels to a pixmap.
  557.  */
  558. static void write_span_TRUECOLOR_pixmap( COLOR_SPAN_ARGS )
  559. {
  560.    register GLuint i;
  561.    y = FLIP(y);
  562.    if (mask) {
  563.       for (i=0;i<n;i++,x++) {
  564.          if (mask[i]) {
  565.             register unsigned long p = PACK_RGB( red[i], green[i], blue[i] );
  566.             XSetForeground( XMesa->display, XMesa->gc2, p );
  567.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  568.                        (int) x, (int) y );
  569.          }
  570.       }
  571.    }
  572.    else {
  573.       /* draw all pixels */
  574.       for (i=0;i<n;i++) {
  575.          XPutPixel( XMesa->rowimage, i, 0,
  576.                     PACK_RGB( red[i], green[i], blue[i] ) );
  577.       }
  578.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  579.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  580.    }
  581. }
  582.  
  583.  
  584. /*
  585.  * Write a span of PF_8A8B8G8R pixels to a pixmap.
  586.  */
  587. static void write_span_8A8B8G8R_pixmap( COLOR_SPAN_ARGS )
  588. {
  589.    register GLuint i;
  590.    y = FLIP( y );
  591.    if (mask) {
  592.       for (i=0;i<n;i++,x++) {
  593.          if (mask[i]) {
  594.             register unsigned long p;
  595.             p = (alpha[i]<<24) | (blue[i]<<16) | (green[i]<<8) | red[i];
  596.             XSetForeground( XMesa->display, XMesa->gc2, p );
  597.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  598.                         (int) x, (int) y );
  599.          }
  600.       }
  601.    }
  602.    else {
  603.       /* draw all pixels */
  604.       register GLuint *ptr4 = (GLuint *) XMesa->rowimage->data;
  605.       for (i=0;i<n;i++) {
  606.          *ptr4++ = (alpha[i]<<24) | (blue[i]<<16) | (green[i]<<8) | red[i];
  607.       }
  608.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  609.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  610.    }
  611. }
  612.  
  613.  
  614. /*
  615.  * Write a span of PF_DITHER pixels to a pixmap.
  616.  */
  617. static void write_span_DITHER_pixmap( COLOR_SPAN_ARGS )
  618. {
  619.    register GLuint i;
  620.    y = FLIP( y );
  621.    if (mask) {
  622.       for (i=0;i<n;i++,x++) {
  623.          if (mask[i]) {
  624.             register unsigned long p;
  625.             p = DITHER_8BIT( x, y, red[i], green[i], blue[i] );
  626.             XSetForeground( XMesa->display, XMesa->gc2, p );
  627.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  628.                         (int) x, (int) y );
  629.          }
  630.       }
  631.    }
  632.    else {
  633.       /* draw all pixels */
  634.       for (i=0;i<n;i++) {
  635.          XPutPixel( XMesa->rowimage, i, 0,
  636.                     DITHER_8BIT( i, y, red[i], green[i], blue[i] ) );
  637.       }
  638.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  639.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  640.    }
  641. }
  642.  
  643.  
  644. /*
  645.  * Write a span of PF_1BIT pixels to a pixmap.
  646.  */
  647. static void write_span_1BIT_pixmap( COLOR_SPAN_ARGS )
  648. {
  649.    register GLuint i;
  650.    y = FLIP( y );
  651.    if (mask) {
  652.       for (i=0;i<n;i++,x++) {
  653.          if (mask[i]) {
  654.             register unsigned long p;
  655.             p = DITHER_1BIT( x, y, red[i], green[i], blue[i] );
  656.             XSetForeground( XMesa->display, XMesa->gc2, p );
  657.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  658.                         (int) x, (int) y );
  659.          }
  660.       }
  661.    }
  662.    else {
  663.       /* draw all pixels */
  664.       for (i=0;i<n;i++) {
  665.          XPutPixel( XMesa->rowimage, i, 0,
  666.                     DITHER_1BIT( x+i, y, red[i], green[i], blue[i] ) );
  667.       }
  668.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  669.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  670.    }
  671. }
  672.  
  673.  
  674.  
  675. /*
  676.  * Write a span of PF_HPCR pixels to a pixmap.
  677.  */
  678. static void write_span_HPCR_pixmap( COLOR_SPAN_ARGS )
  679. {
  680.    register GLuint i;
  681.    y = FLIP( y );
  682.    if (mask) {
  683.       for (i=0;i<n;i++,x++) {
  684.          if (mask[i]) {
  685.             register unsigned long p;
  686.             p = DITHER_HPCR( x, y, red[i], green[i], blue[i] );
  687.             XSetForeground( XMesa->display, XMesa->gc2, p );
  688.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  689.                        (int) x, (int) y );
  690.          }
  691.       }
  692.    }
  693.    else {
  694.       register GLubyte *ptr = (GLubyte *) XMesa->rowimage->data;
  695.       for (i=0;i<n;i++) {
  696.          *ptr++ = DITHER_HPCR( (x+i), y, red[i], green[i], blue[i] );
  697.       }
  698.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  699.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  700.    }
  701. }
  702.  
  703.  
  704. /*
  705.  * Write a span of PF_LOOKUP pixels to a pixmap.
  706.  */
  707. static void write_span_LOOKUP_pixmap( COLOR_SPAN_ARGS )
  708. {
  709.    register GLuint i;
  710.    y = FLIP( y );
  711.    if (mask) {
  712.       for (i=0;i<n;i++,x++) {
  713.          if (mask[i]) {
  714.             register unsigned long p;
  715.             p = LOOKUP( red[i], green[i], blue[i] );
  716.             XSetForeground( XMesa->display, XMesa->gc2, p );
  717.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  718.                        (int) x, (int) y );
  719.          }
  720.       }
  721.    }
  722.    else {
  723.       for (i=0;i<n;i++) {
  724.          XPutPixel( XMesa->rowimage, i, 0, LOOKUP(red[i],green[i],blue[i]) );
  725.       }
  726.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  727.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  728.    }
  729. }
  730.  
  731.  
  732.  
  733. /*
  734.  * Write a span of PF_GRAYSCALE pixels to a pixmap.
  735.  */
  736. static void write_span_GRAYSCALE_pixmap( COLOR_SPAN_ARGS )
  737. {
  738.    register GLuint i;
  739.    y = FLIP( y );
  740.    if (mask) {
  741.       for (i=0;i<n;i++,x++) {
  742.          if (mask[i]) {
  743.             register unsigned long p;
  744.             p = GRAY_RGB( red[i], green[i], blue[i] );
  745.             XSetForeground( XMesa->display, XMesa->gc2, p );
  746.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  747.                        (int) x, (int) y );
  748.          }
  749.       }
  750.    }
  751.    else {
  752.       for (i=0;i<n;i++) {
  753.          XPutPixel( XMesa->rowimage, i, 0, GRAY_RGB(red[i],green[i],blue[i]) );
  754.       }
  755.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  756.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  757.    }
  758. }
  759.  
  760.  
  761.  
  762. /*
  763.  * Write a span of PF_TRUECOLOR pixels to an XImage.
  764.  */
  765. static void write_span_TRUECOLOR_ximage( COLOR_SPAN_ARGS )
  766. {
  767.    register GLuint i;
  768.    y = FLIP(y);
  769.    if (mask) {
  770.       for (i=0;i<n;i++,x++) {
  771.          if (mask[i]) {
  772.             register unsigned long p = PACK_RGB( red[i], green[i], blue[i] );
  773.             XPutPixel( XMesa->backimage, x, y, p );
  774.          }
  775.       }
  776.    }
  777.    else {
  778.       /* draw all pixels */
  779.       for (i=0;i<n;i++,x++) {
  780.          register unsigned long p = PACK_RGB( red[i], green[i], blue[i] );
  781.          XPutPixel( XMesa->backimage, x, y, p );
  782.       }
  783.    }
  784. }
  785.  
  786.  
  787. /*
  788.  * Write a span of PF_8A8B8G8R-format pixels to an ximage.
  789.  */
  790. static void write_span_8A8B8G8R_ximage( COLOR_SPAN_ARGS )
  791. {
  792.    register GLuint i;
  793.    register GLuint *ptr = (GLuint *) XMesa->backimage->data + OFFSET4(x,y);
  794.    if (mask) {
  795.       for (i=0;i<n;i++,ptr++) {
  796.          if (mask[i]) {
  797.             *ptr = (alpha[i] << 24) | (blue[i] << 16) | (green[i] << 8) | red[i];
  798.          }
  799.       }
  800.    }
  801.    else {
  802.       /* draw all pixels */
  803.       for (i=0;i<n;i++,ptr++) {
  804.          *ptr = (alpha[i] << 24) | (blue[i] << 16) | (green[i] << 8) | red[i];
  805.       }
  806.    }
  807. }
  808.  
  809.  
  810.  
  811. /*
  812.  * Write a span of PF_DITHER pixels to an XImage.
  813.  */
  814. static void write_span_DITHER_ximage( COLOR_SPAN_ARGS )
  815. {
  816.    register GLuint i;
  817.    y = FLIP(y);
  818.    if (mask) {
  819.       for (i=0;i<n;i++,x++) {
  820.          if (mask[i]) {
  821.             register unsigned long p;
  822.             p = DITHER_8BIT( x, y, red[i], green[i], blue[i] );
  823.             XPutPixel( XMesa->backimage, x, y, p );
  824.          }
  825.       }
  826.    }
  827.    else {
  828.       /* draw all pixels */
  829.       for (i=0;i<n;i++,x++) {
  830.          register unsigned long p;
  831.          p = DITHER_8BIT( x, y, red[i], green[i], blue[i] );
  832.          XPutPixel( XMesa->backimage, x, y, p );
  833.       }
  834.    }
  835. }
  836.  
  837.  
  838.  
  839. /*
  840.  * Write a span of 8-bit PF_DITHER pixels to an XImage.
  841.  */
  842. static void write_span_DITHER8_ximage( COLOR_SPAN_ARGS )
  843. {
  844.    register GLuint i;
  845.    register GLubyte *ptr = (GLubyte *) XMesa->backimage->data + OFFSET1(x,y);
  846.    if (mask) {
  847.       for (i=0;i<n;i++,x++,ptr++) {
  848.          if (mask[i]) {
  849.             *ptr = DITHER_8BIT( x, y, red[i], green[i], blue[i] );
  850.          }
  851.       }
  852.    }
  853.    else {
  854.       for (i=0;i<n;i++,x++,ptr++) {
  855.          *ptr = DITHER_8BIT( x, y, red[i], green[i], blue[i] );
  856.       }
  857.    }
  858. }
  859.  
  860.  
  861.  
  862. /*
  863.  * Write a span of PF_1BIT pixels to an XImage.
  864.  */
  865. static void write_span_1BIT_ximage( COLOR_SPAN_ARGS )
  866. {
  867.    register GLuint i;
  868.    y = FLIP(y);
  869.    if (mask) {
  870.       for (i=0;i<n;i++,x++) {
  871.          if (mask[i]) {
  872.             register unsigned long p;
  873.             p = DITHER_1BIT( x, y, red[i], green[i], blue[i] );
  874.             XPutPixel( XMesa->backimage, x, y, p );
  875.          }
  876.       }
  877.    }
  878.    else {
  879.       for (i=0;i<n;i++,x++) {
  880.          register unsigned long p;
  881.          p = DITHER_1BIT( x, y, red[i], green[i], blue[i] );
  882.          XPutPixel( XMesa->backimage, x, y, p );
  883.       }
  884.    }
  885. }
  886.  
  887.  
  888. /*
  889.  * Write a span of PF_HPCR pixels to an XImage.
  890.  */
  891. static void write_span_HPCR_ximage( COLOR_SPAN_ARGS )
  892. {
  893.    register GLuint i;
  894.    register GLubyte *ptr;
  895.    ptr = (GLubyte *) XMesa->backimage->data + OFFSET1(x,y);
  896.    if (mask) {
  897.       for (i=0;i<n;i++,x++,ptr++) {
  898.          if (mask[i]) {
  899.             *ptr = DITHER_HPCR( x, y, red[i], green[i], blue[i] );
  900.          }
  901.       }
  902.    }
  903.    else {
  904.       /* draw all pixels */
  905.       for (i=0;i<n;i++,x++,ptr++) {
  906.          *ptr = DITHER_HPCR( x, y, red[i], green[i], blue[i] );
  907.       }
  908.    }
  909. }
  910.  
  911.  
  912. /*
  913.  * Write a span of PF_LOOKUP pixels to an XImage.
  914.  */
  915. static void write_span_LOOKUP_ximage( COLOR_SPAN_ARGS )
  916. {
  917.    register GLuint i;
  918.    y = FLIP(y);
  919.    if (mask) {
  920.       for (i=0;i<n;i++,x++) {
  921.          if (mask[i]) {
  922.             register unsigned long p;
  923.             p = LOOKUP( red[i], green[i], blue[i] );
  924.             XPutPixel( XMesa->backimage, x, y, p );
  925.          }
  926.       }
  927.    }
  928.    else {
  929.       /* draw all pixels */
  930.       for (i=0;i<n;i++,x++) {
  931.          register unsigned long p;
  932.          p = LOOKUP( red[i], green[i], blue[i] );
  933.          XPutPixel( XMesa->backimage, x, y, p );
  934.       }
  935.    }
  936. }
  937.  
  938.  
  939. /*
  940.  * Write a span of PF_GRAYSCALE pixels to an XImage.
  941.  */
  942. static void write_span_GRAYSCALE_ximage( COLOR_SPAN_ARGS )
  943. {
  944.    register GLuint i;
  945.    y = FLIP(y);
  946.    if (mask) {
  947.       for (i=0;i<n;i++,x++) {
  948.          if (mask[i]) {
  949.             register unsigned long p = GRAY_RGB( red[i], green[i], blue[i] );
  950.             XPutPixel( XMesa->backimage, x, y, p );
  951.          }
  952.       }
  953.    }
  954.    else {
  955.       /* draw all pixels */
  956.       for (i=0;i<n;i++,x++) {
  957.          register unsigned long p = GRAY_RGB( red[i], green[i], blue[i] );
  958.          XPutPixel( XMesa->backimage, x, y, p );
  959.       }
  960.    }
  961. }
  962.  
  963.  
  964. /*
  965.  * Write a span of 8-bit PF_GRAYSCALE pixels to an XImage.
  966.  */
  967. static void write_span_GRAYSCALE8_ximage( COLOR_SPAN_ARGS )
  968. {
  969.    register GLuint i;
  970.    register GLubyte *ptr = (GLubyte *) XMesa->backimage->data + OFFSET1(x,y);
  971.    if (mask) {
  972.       for (i=0;i<n;i++,ptr++) {
  973.          if (mask[i]) {
  974.             *ptr = GRAY_RGB( red[i], green[i], blue[i] );
  975.          }
  976.       }
  977.    }
  978.    else {
  979.       /* draw all pixels */
  980.       for (i=0;i<n;i++,ptr++) {
  981.          *ptr = GRAY_RGB( red[i], green[i], blue[i] );
  982.       }
  983.    }
  984. }
  985.  
  986.  
  987.  
  988.  
  989. /**********************************************************************/
  990. /*** Write COLOR PIXEL functions                                    ***/
  991. /**********************************************************************/
  992.  
  993.  
  994. #define COLOR_PIXEL_ARGS   GLuint n, const GLint x[], const GLint y[],    \
  995.                const GLubyte red[], const GLubyte green[],    \
  996.                const GLubyte blue[], const GLubyte alpha[],    \
  997.                const GLubyte mask[]
  998.  
  999.  
  1000. /*
  1001.  * Write an array of PF_TRUECOLOR pixels to a pixmap.
  1002.  */
  1003. static void write_pixels_TRUECOLOR_pixmap( COLOR_PIXEL_ARGS )
  1004. {
  1005.    register GLuint i;
  1006.    for (i=0;i<n;i++) {
  1007.       if (mask[i]) {
  1008.      register unsigned long p;
  1009.      p = PACK_RGB( red[i], green[i], blue[i] );
  1010.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1011.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1012.             (int) x[i], (int) FLIP(y[i]) );
  1013.       }
  1014.    }
  1015. }
  1016.  
  1017.  
  1018. /*
  1019.  * Write an array of PF_8A8B8G8R pixels to a pixmap.
  1020.  */
  1021. static void write_pixels_8A8B8G8R_pixmap( COLOR_PIXEL_ARGS )
  1022. {
  1023.    register GLuint i;
  1024.    for (i=0;i<n;i++) {
  1025.       if (mask[i]) {
  1026.      register unsigned long p;
  1027.      p = (alpha[i]<<24) | (blue[i]<<16) | (green[i]<<8) | red[i];
  1028.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1029.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1030.                  (int) x[i], (int) FLIP(y[i]) );
  1031.       }
  1032.    }
  1033. }
  1034.  
  1035.  
  1036. /*
  1037.  * Write an array of PF_DITHER pixels to a pixmap.
  1038.  */
  1039. static void write_pixels_DITHER_pixmap( COLOR_PIXEL_ARGS )
  1040. {
  1041.    register GLuint i;
  1042.    for (i=0;i<n;i++) {
  1043.       if (mask[i]) {
  1044.      register unsigned long p;
  1045.      p = DITHER_8BIT( x[i], y[i], red[i], green[i], blue[i] );
  1046.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1047.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1048.                  (int) x[i], (int) FLIP(y[i]) );
  1049.       }
  1050.    }
  1051. }
  1052.  
  1053.  
  1054. /*
  1055.  * Write an array of PF_1BIT pixels to a pixmap.
  1056.  */
  1057. static void write_pixels_1BIT_pixmap( COLOR_PIXEL_ARGS )
  1058. {
  1059.    register GLuint i;
  1060.    for (i=0;i<n;i++) {
  1061.       if (mask[i]) {
  1062.      register unsigned long p;
  1063.      p = DITHER_1BIT( x[i], y[i], red[i], green[i], blue[i] );
  1064.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1065.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1066.                  (int) x[i], (int) FLIP(y[i]) );
  1067.       }
  1068.    }
  1069. }
  1070.  
  1071.  
  1072. /*
  1073.  * Write an array of PF_HPCR pixels to a pixmap.
  1074.  */
  1075. static void write_pixels_HPCR_pixmap( COLOR_PIXEL_ARGS )
  1076. {
  1077.    register GLuint i;
  1078.    for (i=0;i<n;i++) {
  1079.       if (mask[i]) {
  1080.          register unsigned long p;
  1081.          p = DITHER_HPCR( x[i], y[i], red[i], green[i], blue[i] );
  1082.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1083.          XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1084.                      (int) x[i], (int) FLIP(y[i]) );
  1085.       }
  1086.    }
  1087. }
  1088.  
  1089.  
  1090. /*
  1091.  * Write an array of PF_LOOKUP pixels to a pixmap.
  1092.  */
  1093. static void write_pixels_LOOKUP_pixmap( COLOR_PIXEL_ARGS )
  1094. {
  1095.    register GLuint i;
  1096.    for (i=0;i<n;i++) {
  1097.       if (mask[i]) {
  1098.          register unsigned long p;
  1099.          p = LOOKUP( red[i], green[i], blue[i] );
  1100.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1101.          XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1102.                      (int) x[i], (int) FLIP(y[i]) );
  1103.       }
  1104.    }
  1105. }
  1106.  
  1107.  
  1108. /*
  1109.  * Write an array of PF_GRAYSCALE pixels to a pixmap.
  1110.  */
  1111. static void write_pixels_GRAYSCALE_pixmap( COLOR_PIXEL_ARGS )
  1112. {
  1113.    register GLuint i;
  1114.    for (i=0;i<n;i++) {
  1115.       if (mask[i]) {
  1116.          register unsigned long p;
  1117.          p = GRAY_RGB( red[i], green[i], blue[i] );
  1118.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1119.          XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1120.                      (int) x[i], (int) FLIP(y[i]) );
  1121.       }
  1122.    }
  1123. }
  1124.  
  1125.  
  1126. /*
  1127.  * Write an array of PF_TRUECOLOR pixels to an ximage.
  1128.  */
  1129. static void write_pixels_TRUECOLOR_ximage( COLOR_PIXEL_ARGS )
  1130. {
  1131.    register GLuint i;
  1132.    for (i=0;i<n;i++) {
  1133.       if (mask[i]) {
  1134.      register unsigned long p;
  1135.      p = PACK_RGBA( red[i], green[i], blue[i], alpha[i] );
  1136.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1137.       }
  1138.    }
  1139. }
  1140.  
  1141.  
  1142. /*
  1143.  * Write an array of PF_8A8B8G8R pixels to an ximage.
  1144.  */
  1145. static void write_pixels_8A8B8G8R_ximage( COLOR_PIXEL_ARGS )
  1146. {
  1147.    register GLuint i;
  1148.    for (i=0;i<n;i++) {
  1149.       if (mask[i]) {
  1150.      GLuint *ptr;
  1151.      ptr = (GLuint *) XMesa->backimage->data + OFFSET4(x[i],y[i]);
  1152.      *ptr = (alpha[i] << 24) | (blue[i] << 16) | (green[i] << 8) | red[i];
  1153.       }
  1154.    }
  1155. }
  1156.  
  1157.  
  1158. /*
  1159.  * Write an array of PF_DITHER pixels to an XImage.
  1160.  */
  1161. static void write_pixels_DITHER_ximage( COLOR_PIXEL_ARGS )
  1162. {
  1163.    register GLuint i;
  1164.    for (i=0;i<n;i++) {
  1165.       if (mask[i]) {
  1166.      register unsigned long p;
  1167.      p = DITHER_8BIT( x[i], y[i], red[i], green[i], blue[i] );
  1168.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1169.       }
  1170.    }
  1171. }
  1172.  
  1173.  
  1174. /*
  1175.  * Write an array of 8-bit PF_DITHER pixels to an XImage.
  1176.  */
  1177. static void write_pixels_DITHER8_ximage( COLOR_PIXEL_ARGS )
  1178. {
  1179.    register GLuint i;
  1180.    for (i=0;i<n;i++) {
  1181.       if (mask[i]) {
  1182.      register GLubyte *ptr;
  1183.      ptr = (GLubyte *) XMesa->backimage->data + OFFSET1(x[i],y[i]);
  1184.      *ptr = DITHER_8BIT( x[i], y[i], red[i], green[i], blue[i] );
  1185.       }
  1186.    }
  1187. }
  1188.  
  1189.  
  1190. /*
  1191.  * Write an array of PF_1BIT pixels to an XImage.
  1192.  */
  1193. static void write_pixels_1BIT_ximage( COLOR_PIXEL_ARGS )
  1194. {
  1195.    register GLuint i;
  1196.    for (i=0;i<n;i++) {
  1197.       if (mask[i]) {
  1198.      register unsigned long p;
  1199.      p = DITHER_1BIT( x[i], y[i], red[i], green[i], blue[i] );
  1200.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1201.       }
  1202.    }
  1203. }
  1204.  
  1205.  
  1206. /*
  1207.  * Write an array of PF_HPCR pixels to an XImage.
  1208.  */
  1209. static void write_pixels_HPCR_ximage( COLOR_PIXEL_ARGS )
  1210. {
  1211.    register GLuint i;
  1212.    for (i=0;i<n;i++) {
  1213.       if (mask[i]) {
  1214.          register GLubyte *ptr;
  1215.          ptr = (GLubyte *) XMesa->backimage->data + OFFSET1(x[i],y[i]);
  1216.          *ptr = DITHER_HPCR( x[i], y[i], red[i], green[i], blue[i] );
  1217.       }
  1218.    }
  1219. }
  1220.  
  1221.  
  1222. /*
  1223.  * Write an array of PF_LOOKUP pixels to an XImage.
  1224.  */
  1225. static void write_pixels_LOOKUP_ximage( COLOR_PIXEL_ARGS )
  1226. {
  1227.    register GLuint i;
  1228.    for (i=0;i<n;i++) {
  1229.       if (mask[i]) {
  1230.          register unsigned long p = LOOKUP( red[i], green[i], blue[i] );
  1231.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1232.       }
  1233.    }
  1234. }
  1235.  
  1236.  
  1237. /*
  1238.  * Write an array of PF_GRAYSCALE pixels to an XImage.
  1239.  */
  1240. static void write_pixels_GRAYSCALE_ximage( COLOR_PIXEL_ARGS )
  1241. {
  1242.    register GLuint i;
  1243.    for (i=0;i<n;i++) {
  1244.       if (mask[i]) {
  1245.      register unsigned long p = GRAY_RGB( red[i], green[i], blue[i] );
  1246.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1247.       }
  1248.    }
  1249. }
  1250.  
  1251.  
  1252. /*
  1253.  * Write an array of 8-bit PF_GRAYSCALE pixels to an XImage.
  1254.  */
  1255. static void write_pixels_GRAYSCALE8_ximage( COLOR_PIXEL_ARGS )
  1256. {
  1257.    register GLuint i;
  1258.    for (i=0;i<n;i++) {
  1259.       if (mask[i]) {
  1260.      register GLubyte *ptr;
  1261.      ptr = (GLubyte *) XMesa->backimage->data + OFFSET1(x[i],y[i]);
  1262.      *ptr = GRAY_RGB( red[i], green[i], blue[i] );
  1263.       }
  1264.    }
  1265. }
  1266.  
  1267.  
  1268.  
  1269.  
  1270. /**********************************************************************/
  1271. /*** Write MONO COLOR SPAN functions                                ***/
  1272. /**********************************************************************/
  1273.  
  1274. #define MONO_SPAN_ARGS  GLuint n, GLint x, GLint y, const GLubyte mask[]
  1275.  
  1276.  
  1277. /*
  1278.  * Write a span of identical pixels to a pixmap.  The pixel value is
  1279.  * the one set by DD.color() or DD.index().
  1280.  */
  1281. static void write_span_mono_pixmap( MONO_SPAN_ARGS )
  1282. {
  1283.    register GLuint i;
  1284.    register GLboolean write_all;
  1285.    y = FLIP( y );
  1286.    write_all = GL_TRUE;
  1287.    for (i=0;i<n;i++) {
  1288.       if (!mask[i]) {
  1289.      write_all = GL_FALSE;
  1290.      break;
  1291.       }
  1292.    }
  1293.    if (write_all) {
  1294.       XFillRectangle( XMesa->display, XMesa->buffer, XMesa->gc1,
  1295.               (int) x, (int) y, n, 1 );
  1296.    }
  1297.    else {
  1298.       for (i=0;i<n;i++,x++) {
  1299.      if (mask[i]) {
  1300.         XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc1,
  1301.                 (int) x, (int) y );
  1302.      }
  1303.       }
  1304.    }
  1305. }
  1306.  
  1307.  
  1308. /*
  1309.  * Write a span of PF_DITHER pixels to a pixmap.  The pixel value is
  1310.  * the one set by DD.color() or DD.index().
  1311.  */
  1312. static void write_span_mono_DITHER_pixmap( MONO_SPAN_ARGS )
  1313. {
  1314.    register GLuint i;
  1315.    register unsigned long p = XMesa->pixel;
  1316.    register GLubyte r, g, b;
  1317.    r = XMesa->red;
  1318.    g = XMesa->green;
  1319.    b = XMesa->blue;
  1320.    y = FLIP( y );
  1321.    for (i=0;i<n;i++,x++) {
  1322.       if (mask[i]) {
  1323.          p = DITHER_8BIT( x, y, r, g, b );
  1324.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1325.          XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1326.                     (int) x, (int) y );
  1327.       }
  1328.    }
  1329. }
  1330.  
  1331.  
  1332. /*
  1333.  * Write a span of identical pixels to an XImage.  The pixel value is
  1334.  * the one set by DD.color() or DD.index().
  1335.  */
  1336. static void write_span_mono_ximage( MONO_SPAN_ARGS )
  1337. {
  1338.    register GLuint i;
  1339.    register unsigned long p = XMesa->pixel;
  1340.    y = FLIP( y );
  1341.    for (i=0;i<n;i++,x++) {
  1342.       if (mask[i]) {
  1343.      XPutPixel( XMesa->backimage, x, y, p );
  1344.       }
  1345.    }
  1346. }
  1347.  
  1348.  
  1349. /*
  1350.  * Write a span of identical 8A8B8G8R pixels to an XImage.  The pixel
  1351.  * value is the one set by DD.color().
  1352.  */
  1353. static void write_span_mono_8A8B8G8R_ximage( MONO_SPAN_ARGS )
  1354. {
  1355.    register GLuint i, p, *ptr;
  1356.    p = (GLuint) XMesa->pixel;
  1357.    ptr = (GLuint *) XMesa->backimage->data + OFFSET4(x,y);
  1358.    for (i=0;i<n;i++,ptr++) {
  1359.       if (mask[i]) {
  1360.      *ptr = p;
  1361.       }
  1362.    }
  1363. }
  1364.  
  1365.  
  1366. /*
  1367.  * Write a span of identical DITHER pixels to an XImage.  The pixel
  1368.  * value is the one set by DD.color().
  1369.  */
  1370. static void write_span_mono_DITHER_ximage( MONO_SPAN_ARGS )
  1371. {
  1372.    register GLuint i;
  1373.    register GLubyte r, g, b;
  1374.    r = XMesa->red;
  1375.    g = XMesa->green;
  1376.    b = XMesa->blue;
  1377.    y = FLIP(y);
  1378.    for (i=0;i<n;i++,x++) {
  1379.       if (mask[i]) {
  1380.      unsigned long p = DITHER_8BIT( x, y, r, g, b );
  1381.      XPutPixel( XMesa->backimage, x, y, p );
  1382.       }
  1383.    }
  1384. }
  1385.  
  1386.  
  1387. /*
  1388.  * Write a span of identical 8-bit DITHER pixels to an XImage.  The pixel
  1389.  * value is the one set by DD.color().
  1390.  */
  1391. static void write_span_mono_DITHER8_ximage( MONO_SPAN_ARGS )
  1392. {
  1393.    register GLuint i;
  1394.    register GLbyte *ptr = (GLbyte *) XMesa->backimage->data + OFFSET1(x,y);
  1395.    register GLubyte r, g, b;
  1396.    r = XMesa->red;
  1397.    g = XMesa->green;
  1398.    b = XMesa->blue;
  1399.    for (i=0;i<n;i++,ptr++,x++) {
  1400.       if (mask[i]) {
  1401.      *ptr = DITHER_8BIT( x, y, r, g, b );
  1402.       }
  1403.    }
  1404. }
  1405.  
  1406.  
  1407. /*
  1408.  * Write a span of identical HPCR pixels to an XImage.  The pixel
  1409.  * value is the one set by DD.color().
  1410.  */
  1411. static void write_span_mono_HPCR_ximage( MONO_SPAN_ARGS )
  1412. {
  1413.    register GLuint i;
  1414.    register GLbyte *ptr = (GLbyte *) XMesa->backimage->data + OFFSET1(x,y);
  1415.    register GLubyte r, g, b;
  1416.    r = XMesa->red;
  1417.    g = XMesa->green;
  1418.    b = XMesa->blue;
  1419.    for (i=0;i<n;i++,ptr++,x++) {
  1420.       if (mask[i]) {
  1421.          *ptr = DITHER_HPCR( x, y, r, g, b );
  1422.       }
  1423.    }
  1424. }
  1425.  
  1426.  
  1427.  
  1428. /*
  1429.  * Write a span of identical 8-bit GRAYSCALE pixels to an XImage.  The pixel
  1430.  * value is the one set by DD.color().
  1431.  */
  1432. static void write_span_mono_GRAYSCALE8_ximage( MONO_SPAN_ARGS )
  1433. {
  1434.    register GLuint i;
  1435.    unsigned long p = XMesa->pixel;
  1436.    register GLbyte *ptr = (GLbyte *) XMesa->backimage->data + OFFSET1(x,y);
  1437.    for (i=0;i<n;i++,ptr++) {
  1438.       if (mask[i]) {
  1439.      *ptr = p;
  1440.       }
  1441.    }
  1442. }
  1443.  
  1444.  
  1445. /**********************************************************************/
  1446. /*** Write MONO COLOR PIXELS functions                              ***/
  1447. /**********************************************************************/
  1448.  
  1449. #define MONO_PIXEL_ARGS        GLuint n, const GLint x[], const GLint y[], \
  1450.                 const GLubyte mask[]
  1451.  
  1452. /*
  1453.  * Write an array of identical pixels to a pixmap.  The pixel value is
  1454.  * the one set by DD.color() or DD.index.
  1455.  */
  1456. static void write_pixels_mono_pixmap( MONO_PIXEL_ARGS )
  1457. {
  1458.    register GLuint i;
  1459.    for (i=0;i<n;i++) {
  1460.       if (mask[i]) {
  1461.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc1,
  1462.             (int) x[i], (int) FLIP(y[i]) );
  1463.       }
  1464.    }
  1465. }
  1466.  
  1467.  
  1468. /*
  1469.  * Write an array of PF_DITHER pixels to a pixmap.  The pixel value is
  1470.  * the one set by DD.color() or DD.index.
  1471.  */
  1472. static void write_pixels_mono_DITHER_pixmap( MONO_PIXEL_ARGS )
  1473. {
  1474.    register GLuint i;
  1475.    register GLubyte r, g, b;
  1476.    r = XMesa->red;
  1477.    g = XMesa->green;
  1478.    b = XMesa->blue;
  1479.    for (i=0;i<n;i++) {
  1480.       if (mask[i]) {
  1481.          unsigned long p = DITHER_8BIT( x[i], y[i], r, g, b );
  1482.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1483.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1484.             (int) x[i], (int) FLIP(y[i]) );
  1485.       }
  1486.    }
  1487. }
  1488.  
  1489.  
  1490. /*
  1491.  * Write an array of identical pixels to an XImage.  The pixel value is
  1492.  * the one set by DD.color() or DD.index.
  1493.  */
  1494. static void write_pixels_mono_ximage( MONO_PIXEL_ARGS )
  1495. {
  1496.    register GLuint i;
  1497.    register unsigned long p = XMesa->pixel;
  1498.    for (i=0;i<n;i++) {
  1499.       if (mask[i]) {
  1500.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1501.       }
  1502.    }
  1503. }
  1504.  
  1505.  
  1506.  
  1507. /*
  1508.  * Write an array of identical 8A8B8G8R pixels to an XImage.  The pixel value
  1509.  * is the one set by DD.color().
  1510.  */
  1511. static void write_pixels_mono_8A8B8G8R_ximage( MONO_PIXEL_ARGS )
  1512. {
  1513.    register GLuint i;
  1514.    register GLuint p = (GLuint) XMesa->pixel;
  1515.    for (i=0;i<n;i++) {
  1516.       if (mask[i]) {
  1517.      register GLuint *ptr;
  1518.      ptr = (GLuint *) XMesa->backimage->data + OFFSET4(x[i],y[i]);
  1519.      *ptr = p;
  1520.       }
  1521.    }
  1522. }
  1523.  
  1524.  
  1525. /*
  1526.  * Write an array of identical PF_DITHER pixels to an XImage.  The pixel
  1527.  * value is the one set by DD.color().
  1528.  */
  1529. static void write_pixels_mono_DITHER_ximage( MONO_PIXEL_ARGS )
  1530. {
  1531.    register GLuint i;
  1532.    register GLubyte r, g, b;
  1533.    r = XMesa->red;
  1534.    g = XMesa->green;
  1535.    b = XMesa->blue;
  1536.    for (i=0;i<n;i++) {
  1537.       if (mask[i]) {
  1538.      unsigned long p = DITHER_8BIT( x[i], y[i], r, g, b );
  1539.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1540.       }
  1541.    }
  1542. }
  1543.  
  1544.  
  1545. /*
  1546.  * Write an array of identical 8-bit PF_DITHER pixels to an XImage.  The
  1547.  * pixel value is the one set by DD.color().
  1548.  */
  1549. static void write_pixels_mono_DITHER8_ximage( MONO_PIXEL_ARGS )
  1550. {
  1551.    register GLuint i;
  1552.    register GLubyte r, g, b;
  1553.    r = XMesa->red;
  1554.    g = XMesa->green;
  1555.    b = XMesa->blue;
  1556.    for (i=0;i<n;i++) {
  1557.       if (mask[i]) {
  1558.      register GLubyte *ptr;
  1559.      ptr = (GLubyte *) XMesa->backimage->data + OFFSET1(x[i],y[i]);
  1560.      *ptr = DITHER_8BIT( x[i], y[i], r, g, b );
  1561.       }
  1562.    }
  1563. }
  1564.  
  1565.  
  1566. /*
  1567.  * Write an array of identical PF_HPCR pixels to an XImage.  The
  1568.  * pixel value is the one set by DD.color().
  1569.  */
  1570. static void write_pixels_mono_HPCR_ximage( MONO_PIXEL_ARGS )
  1571. {
  1572.    register GLuint i;
  1573.    register GLubyte r, g, b;
  1574.    r = XMesa->red;
  1575.    g = XMesa->green;
  1576.    b = XMesa->blue;
  1577.    for (i=0;i<n;i++) {
  1578.       if (mask[i]) {
  1579.          register GLubyte *ptr;
  1580.          ptr = (GLubyte *) XMesa->backimage->data + OFFSET1(x[i],y[i]);
  1581.          *ptr = DITHER_HPCR( x[i], y[i], r, g, b );
  1582.       }
  1583.    }
  1584. }
  1585.  
  1586.  
  1587. /*
  1588.  * Write an array of identical 8-bit PF_GRAYSCALE pixels to an XImage.  The
  1589.  * pixel value is the one set by DD.color().
  1590.  */
  1591. static void write_pixels_mono_GRAYSCALE8_ximage( MONO_PIXEL_ARGS )
  1592. {
  1593.    register GLuint i;
  1594.    register unsigned long p = XMesa->pixel;
  1595.    for (i=0;i<n;i++) {
  1596.       if (mask[i]) {
  1597.      register GLubyte *ptr;
  1598.      ptr = (GLubyte *) XMesa->backimage->data + OFFSET1(x[i],y[i]);
  1599.      *ptr = p;
  1600.       }
  1601.    }
  1602. }
  1603.  
  1604.  
  1605.  
  1606.  
  1607. /**********************************************************************/
  1608. /*** Write INDEX SPAN functions                                     ***/
  1609. /**********************************************************************/
  1610.  
  1611. #define INDEX_SPAN_ARGS   GLuint n, GLint x, GLint y, const GLuint index[], \
  1612.               const GLubyte mask[]
  1613.  
  1614.  
  1615. /*
  1616.  * Write a span of CI pixels to a Pixmap.
  1617.  */
  1618. static void write_span_index_pixmap( INDEX_SPAN_ARGS )
  1619. {
  1620.    register GLuint i;
  1621.    y = FLIP(y);
  1622.    for (i=0;i<n;i++,x++) {
  1623.       if (mask[i]) {
  1624.      XSetForeground( XMesa->display, XMesa->gc2,
  1625.              (unsigned long) index[i] );
  1626.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2, (int) x, (int) y );
  1627.       }
  1628.    }
  1629. }
  1630.  
  1631.  
  1632. /*
  1633.  * Write a span of CI pixels to an XImage.
  1634.  */
  1635. static void write_span_index_ximage( INDEX_SPAN_ARGS )
  1636. {
  1637.    register GLuint i;
  1638.    y = FLIP(y);
  1639.    for (i=0;i<n;i++,x++) {
  1640.       if (mask[i]) {
  1641.      XPutPixel( XMesa->backimage, x, y, (unsigned long) index[i] );
  1642.       }
  1643.    }
  1644. }
  1645.  
  1646.  
  1647.  
  1648. /**********************************************************************/
  1649. /*** Write INDEX PIXELS functions                                   ***/
  1650. /**********************************************************************/
  1651.  
  1652. #define INDEX_PIXELS_ARGS    GLuint n, const GLint x[], const GLint y[], \
  1653.                 const GLuint index[], const GLubyte mask[]
  1654.  
  1655.  
  1656. /*
  1657.  * Write an array of CI pixels to a Pixmap.
  1658.  */
  1659. static void write_pixels_index_pixmap( INDEX_PIXELS_ARGS )
  1660. {
  1661.    register GLuint i;
  1662.    for (i=0;i<n;i++) {
  1663.       if (mask[i]) {
  1664.      XSetForeground( XMesa->display, XMesa->gc2,
  1665.              (unsigned long) index[i] );
  1666.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2, 
  1667.              (int) x[i], (int) FLIP(y[i]) );
  1668.       }
  1669.    }
  1670. }
  1671.  
  1672.  
  1673. /*
  1674.  * Write an array of CI pixels to an XImage.
  1675.  */
  1676. static void write_pixels_index_ximage( INDEX_PIXELS_ARGS )
  1677. {
  1678.    register GLuint i;
  1679.    for (i=0;i<n;i++) {
  1680.       if (mask[i]) {
  1681.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), (unsigned long) index[i] );
  1682.       }
  1683.    }
  1684. }
  1685.  
  1686.  
  1687.  
  1688.  
  1689. /**********************************************************************/
  1690. /*****                      Pixel reading                         *****/
  1691. /**********************************************************************/
  1692.  
  1693.  
  1694.  
  1695. /*
  1696.  * Read a horizontal span of color-index pixels.
  1697.  */
  1698. static void read_index_span( GLuint n, GLint x, GLint y, GLuint index[] )
  1699. {
  1700.    int i;
  1701.  
  1702.    y = FLIP(y);
  1703.  
  1704.    if (XMesa->buffer) {
  1705.       XImage *span;
  1706.       span = XGetImage( XMesa->display, XMesa->buffer,
  1707.                 x, y, n, 1, AllPlanes, ZPixmap );
  1708.       if (span) {
  1709.      for (i=0;i<n;i++) {
  1710.         index[i] = (GLuint) XGetPixel( span, i, 0 );
  1711.      }
  1712.      XDestroyImage( span );
  1713.       }
  1714.       else {
  1715.      /* return 0 pixels */
  1716.      for (i=0;i<n;i++) {
  1717.         index[i] = 0;
  1718.      }
  1719.       }
  1720.    }
  1721.    else if (XMesa->backimage) {
  1722.       for (i=0;i<n;i++,x++) {
  1723.      index[i] = (GLuint) XGetPixel( XMesa->backimage, x, y );
  1724.       }
  1725.    }
  1726. }
  1727.  
  1728.  
  1729.  
  1730. /*
  1731.  * Read a horizontal span of color pixels.
  1732.  */
  1733. static void read_color_span( GLuint n, GLint x, GLint y,
  1734.                              GLubyte red[], GLubyte green[],
  1735.                              GLubyte blue[], GLubyte alpha[] )
  1736. {
  1737.    register GLuint i;
  1738.  
  1739.    if (XMesa->buffer) {
  1740.       XImage *span;
  1741.       span = XGetImage( XMesa->display, XMesa->buffer,
  1742.                 x, FLIP(y), n, 1, AllPlanes, ZPixmap );
  1743.       if (span) {
  1744.      switch (XMesa->pixelformat) {
  1745.         case PF_TRUECOLOR:
  1746.             case PF_HPCR:
  1747.                {
  1748.                   GLint rshift = XMesa->rshift, rmult = XMesa->rmult;
  1749.                   GLint gshift = XMesa->gshift, gmult = XMesa->gmult;
  1750.                   GLint bshift = XMesa->bshift, bmult = XMesa->bmult;
  1751.                   GLint ashift = XMesa->ashift, amult = XMesa->amult;
  1752.                   for (i=0;i<n;i++) {
  1753.                      unsigned long p = XGetPixel( span, i, 0 );
  1754.                      red[i]   = (GLubyte) ((p >> rshift) & rmult);
  1755.                      green[i] = (GLubyte) ((p >> gshift) & gmult);
  1756.                      blue[i]  = (GLubyte) ((p >> bshift) & bmult);
  1757.                      alpha[i] = (GLubyte) ((p >> ashift) & amult);
  1758.                   }
  1759.                }
  1760.            break;
  1761.         case PF_8A8B8G8R:
  1762.                {
  1763.                   GLuint *ptr4 = (GLuint *) span->data;
  1764.                   for (i=0;i<n;i++) {
  1765.                      GLuint p4 = *ptr4++;
  1766.                      red[i]   = (GLubyte) ( p4        & 0xff);
  1767.                      green[i] = (GLubyte) ((p4 >> 8)  & 0xff);
  1768.                      blue[i]  = (GLubyte) ((p4 >> 16) & 0xff);
  1769.                      alpha[i] = (GLubyte) ((p4 >> 24) & 0xff);
  1770.                   }
  1771.            }
  1772.            break;
  1773.         case PF_DITHER:
  1774.         case PF_LOOKUP:
  1775.         case PF_GRAYSCALE:
  1776.                {
  1777.                   GLubyte *red_table   = XMesa->red_table;
  1778.                   GLubyte *green_table = XMesa->green_table;
  1779.                   GLubyte *blue_table  = XMesa->blue_table;
  1780.                   if (XMesa->depth==8) {
  1781.                      GLubyte *ptr1 = (GLubyte *) span->data;
  1782.                      for (i=0;i<n;i++) {
  1783.                         unsigned long p = *ptr1++;
  1784.                         red[i]   = red_table[p];
  1785.                         green[i] = green_table[p];
  1786.                         blue[i]  = blue_table[p];
  1787.                         alpha[i] = 255;
  1788.                      }
  1789.                   }
  1790.                   else {
  1791.                      for (i=0;i<n;i++) {
  1792.                         unsigned long p = XGetPixel( span, i, 0 );
  1793.                         red[i]   = red_table[p];
  1794.                         green[i] = green_table[p];
  1795.                         blue[i]  = blue_table[p];
  1796.                         alpha[i] = 255;
  1797.                      }
  1798.                   }
  1799.                }
  1800.            break;
  1801.         case PF_1BIT:
  1802.            for (i=0;i<n;i++) {
  1803.           unsigned long p = XGetPixel( span, i, 0 );
  1804.           red[i]   = (GLubyte) (p * 255);
  1805.           green[i] = (GLubyte) (p * 255);
  1806.           blue[i]  = (GLubyte) (p * 255);
  1807.           alpha[i] = 255;
  1808.            }
  1809.            break;
  1810.         default:
  1811.            die("Problem in DD.read_color_span (1)");
  1812.      }
  1813.      XDestroyImage( span );
  1814.       }
  1815.       else {
  1816.      /* return black pixels */
  1817.      for (i=0;i<n;i++) {
  1818.         red[i] = green[i] = blue[i] = alpha[i] = 0;
  1819.      }
  1820.       }
  1821.    }
  1822.    else if (XMesa->backimage) {
  1823.       switch (XMesa->pixelformat) {
  1824.      case PF_TRUECOLOR:
  1825.          case PF_HPCR:
  1826.             {
  1827.                GLint rshift = XMesa->rshift, rmult = XMesa->rmult;
  1828.                GLint gshift = XMesa->gshift, gmult = XMesa->gmult;
  1829.                GLint bshift = XMesa->bshift, bmult = XMesa->bmult;
  1830.                GLint ashift = XMesa->ashift, amult = XMesa->amult;
  1831.                y = FLIP(y);
  1832.                for (i=0;i<n;i++,x++) {
  1833.                   unsigned long p = XGetPixel( XMesa->backimage, x, y );
  1834.                   red[i]   = (GLubyte) ((p >> rshift) & rmult);
  1835.                   green[i] = (GLubyte) ((p >> gshift) & gmult);
  1836.                   blue[i]  = (GLubyte) ((p >> bshift) & bmult);
  1837.                   alpha[i] = (GLubyte) ((p >> ashift) & amult);
  1838.                }
  1839.             }
  1840.         break;
  1841.      case PF_8A8B8G8R:
  1842.             {
  1843.                GLuint *ptr4 = (GLuint *) XMesa->backimage->data + OFFSET4(x,y);
  1844.                for (i=0;i<n;i++) {
  1845.                   GLuint p4 = *ptr4++;
  1846.                   red[i]   = (GLubyte) ( p4        & 0xff);
  1847.                   green[i] = (GLubyte) ((p4 >> 8)  & 0xff);
  1848.                   blue[i]  = (GLubyte) ((p4 >> 16) & 0xff);
  1849.                   alpha[i] = (GLint) ((p4 >> 24) & 0xff);
  1850.                }
  1851.             }
  1852.         break;
  1853.      case PF_DITHER:
  1854.      case PF_LOOKUP:
  1855.      case PF_GRAYSCALE:
  1856.             {
  1857.                GLubyte *red_table   = XMesa->red_table;
  1858.                GLubyte *green_table = XMesa->green_table;
  1859.                GLubyte *blue_table  = XMesa->blue_table;
  1860.                if (XMesa->depth==8) {
  1861.                   GLubyte *ptr1 = (GLubyte *) XMesa->backimage->data + OFFSET1(x,y);
  1862.                   for (i=0;i<n;i++) {
  1863.                      unsigned long p = *ptr1++;
  1864.                      red[i]   = red_table[p];
  1865.                      green[i] = green_table[p];
  1866.                      blue[i]  = blue_table[p];
  1867.                      alpha[i] = 255;
  1868.                   }
  1869.                }
  1870.                else {
  1871.                   y = FLIP(y);
  1872.                   for (i=0;i<n;i++,x++) {
  1873.                      unsigned long p = XGetPixel( XMesa->backimage, x, y );
  1874.                      red[i]   = red_table[p];
  1875.                      green[i] = green_table[p];
  1876.                      blue[i]  = blue_table[p];
  1877.                      alpha[i] = 255;
  1878.                   }
  1879.                }
  1880.             }
  1881.         break;
  1882.      case PF_1BIT:
  1883.             y = FLIP(y);
  1884.         for (i=0;i<n;i++,x++) {
  1885.            unsigned long p = XGetPixel( XMesa->backimage, x, y );
  1886.            red[i]   = (GLubyte) (p * 255);
  1887.            green[i] = (GLubyte) (p * 255);
  1888.            blue[i]  = (GLubyte) (p * 255);
  1889.            alpha[i] = 255;
  1890.         }
  1891.         break;
  1892.      default:
  1893.         die("Problem in DD.read_color_span (2)");
  1894.       }
  1895.    }
  1896. }
  1897.  
  1898.  
  1899.  
  1900. /*
  1901.  * Read an array of color index pixels.
  1902.  */
  1903. static void read_index_pixels( GLuint n, const GLint x[], const GLint y[],
  1904.                                GLuint indx[], const GLubyte mask[] )
  1905. {
  1906.    register GLuint i;
  1907.    if (XMesa->buffer) {
  1908.       for (i=0;i<n;i++) {
  1909.          if (mask[i]) {
  1910.             indx[i] = (GLuint) read_pixel( XMesa->display, XMesa->buffer,
  1911.                                            x[i], FLIP(y[i]) );
  1912.          }
  1913.       }
  1914.    }
  1915.    else if (XMesa->backimage) {
  1916.       for (i=0;i<n;i++) {
  1917.          if (mask[i]) {
  1918.             indx[i] = (GLuint) XGetPixel( XMesa->backimage, x[i], FLIP(y[i]) );
  1919.          }
  1920.       }
  1921.    }
  1922. }
  1923.  
  1924.  
  1925.  
  1926. static void read_color_pixels( GLuint n, const GLint x[], const GLint y[],
  1927.                                GLubyte red[], GLubyte green[],
  1928.                                GLubyte blue[], GLubyte alpha[],
  1929.                                const GLubyte mask[] )
  1930. {
  1931.    register GLuint i;
  1932.  
  1933.    if (XMesa->buffer) {
  1934.       switch (XMesa->pixelformat) {
  1935.      case PF_TRUECOLOR:
  1936.          case PF_HPCR:
  1937.             {
  1938.                GLint rshift = XMesa->rshift, rmult = XMesa->rmult;
  1939.                GLint gshift = XMesa->gshift, gmult = XMesa->gmult;
  1940.                GLint bshift = XMesa->bshift, bmult = XMesa->bmult;
  1941.                GLint ashift = XMesa->ashift, amult = XMesa->amult;
  1942.                for (i=0;i<n;i++) {
  1943.                   if (mask[i] ) {
  1944.                      unsigned long p = read_pixel( XMesa->display,
  1945.                                           XMesa->buffer, x[i], FLIP(y[i]) );
  1946.                      red[i]   = (GLubyte) ((p >> rshift) & rmult);
  1947.                      green[i] = (GLubyte) ((p >> gshift) & gmult);
  1948.                      blue[i]  = (GLubyte) ((p >> bshift) & bmult);
  1949.                      alpha[i] = XMesa->amult;
  1950.                   }
  1951.                }
  1952.         }
  1953.         break;
  1954.      case PF_8A8B8G8R:
  1955.         for (i=0;i<n;i++) {
  1956.                if (mask[i]) {
  1957.                   unsigned long p = read_pixel( XMesa->display, XMesa->buffer,
  1958.                                                 x[i], FLIP(y[i]) );
  1959.                   red[i]   = (GLubyte) ( p        & 0xff);
  1960.                   green[i] = (GLubyte) ((p >> 8)  & 0xff);
  1961.                   blue[i]  = (GLubyte) ((p >> 16) & 0xff);
  1962.                   alpha[i] = (GLubyte) ((p >> 24) & 0xff);
  1963.                }
  1964.         }
  1965.         break;
  1966.      case PF_DITHER:
  1967.      case PF_LOOKUP:
  1968.      case PF_GRAYSCALE:
  1969.             {
  1970.                GLubyte *red_table   = XMesa->red_table;
  1971.                GLubyte *green_table = XMesa->green_table;
  1972.                GLubyte *blue_table  = XMesa->blue_table;
  1973.                for (i=0;i<n;i++) {
  1974.                   if (mask[i]) {
  1975.                      unsigned long p = read_pixel( XMesa->display,
  1976.                                          XMesa->buffer, x[i], FLIP(y[i]) );
  1977.                      red[i]   = red_table[p];
  1978.                      green[i] = green_table[p];
  1979.                      blue[i]  = blue_table[p];
  1980.                      alpha[i] = 255;
  1981.                   }
  1982.                }
  1983.         }
  1984.         break;
  1985.      case PF_1BIT:
  1986.         for (i=0;i<n;i++) {
  1987.                if (mask[i]) {
  1988.                   unsigned long p = read_pixel( XMesa->display, XMesa->buffer,
  1989.                                                 x[i], FLIP(y[i]) );
  1990.                   red[i]   = (GLubyte) (p * 255);
  1991.                   green[i] = (GLubyte) (p * 255);
  1992.                   blue[i]  = (GLubyte) (p * 255);
  1993.                   alpha[i] = 255;
  1994.                }
  1995.         }
  1996.         break;
  1997.      default:
  1998.         die("Problem in DD.read_color_pixels (1)");
  1999.       }
  2000.    }
  2001.    else if (XMesa->backimage) {
  2002.       switch (XMesa->pixelformat) {
  2003.      case PF_TRUECOLOR:
  2004.          case PF_HPCR:
  2005.             {
  2006.                GLint rshift = XMesa->rshift, rmult = XMesa->rmult;
  2007.                GLint gshift = XMesa->gshift, gmult = XMesa->gmult;
  2008.                GLint bshift = XMesa->bshift, bmult = XMesa->bmult;
  2009.                GLint ashift = XMesa->ashift, amult = XMesa->amult;
  2010.                for (i=0;i<n;i++) {
  2011.                   if (mask[i]) {
  2012.                      unsigned long p;
  2013.                      p = XGetPixel( XMesa->backimage, x[i], FLIP(y[i]) );
  2014.                      red[i]   = (GLubyte) ((p >> rshift) & rmult);
  2015.                      green[i] = (GLubyte) ((p >> gshift) & gmult);
  2016.                      blue[i]  = (GLubyte) ((p >> bshift) & bmult);
  2017.                      alpha[i] = XMesa->amult;
  2018.                   }
  2019.                }
  2020.         }
  2021.         break;
  2022.      case PF_8A8B8G8R:
  2023.         for (i=0;i<n;i++) {
  2024.            if (mask[i]) {
  2025.                   GLuint *ptr4, p4;
  2026.                   ptr4 = (GLuint *) XMesa->backimage->data +OFFSET4(x[i],y[i]);
  2027.                   p4 = *ptr4;
  2028.                   red[i]   = (GLubyte) ( p4        & 0xff);
  2029.                   green[i] = (GLubyte) ((p4 >> 8)  & 0xff);
  2030.                   blue[i]  = (GLubyte) ((p4 >> 16) & 0xff);
  2031.                   alpha[i] = (GLubyte) ((p4 >> 24) & 0xff);
  2032.                }
  2033.         }
  2034.         break;
  2035.      case PF_DITHER:
  2036.      case PF_LOOKUP:
  2037.      case PF_GRAYSCALE:
  2038.             {
  2039.                GLubyte *red_table   = XMesa->red_table;
  2040.                GLubyte *green_table = XMesa->green_table;
  2041.                GLubyte *blue_table  = XMesa->blue_table;
  2042.                for (i=0;i<n;i++) {
  2043.                   if (mask[i]) {
  2044.                      unsigned long p;
  2045.                      p = XGetPixel( XMesa->backimage, x[i], FLIP(y[i]) );
  2046.                      red[i]   = red_table[p];
  2047.                      green[i] = green_table[p];
  2048.                      blue[i]  = blue_table[p];
  2049.                      alpha[i] = 255;
  2050.                   }
  2051.                }
  2052.         }
  2053.         break;
  2054.      case PF_1BIT:
  2055.         for (i=0;i<n;i++) {
  2056.                if (mask[i]) {
  2057.                   unsigned long p;
  2058.                   p = XGetPixel( XMesa->backimage, x[i], FLIP(y[i]) );
  2059.                   red[i]   = (GLubyte) (p * 255);
  2060.                   green[i] = (GLubyte) (p * 255);
  2061.                   blue[i]  = (GLubyte) (p * 255);
  2062.                   alpha[i] = 255;
  2063.                }
  2064.         }
  2065.         break;
  2066.      default:
  2067.         die("Problem in DD.read_color_pixels (1)");
  2068.       }
  2069.    }
  2070. }
  2071.  
  2072.  
  2073.  
  2074.  
  2075. /*
  2076.  * Initialize all the DD.* function pointers depeding on the current
  2077.  * color buffer configuration.  This is mainly called by XMesaMakeCurrent.
  2078.  */
  2079. void xmesa_setup_DD_pointers( void )
  2080. {
  2081.  
  2082.    /*
  2083.     * Always the same:
  2084.     */
  2085.    DD.buffer_size = buffer_size;
  2086.    DD.flush = flush;
  2087.    DD.finish = finish;
  2088.  
  2089.    DD.set_buffer = set_buffer;
  2090.  
  2091.    DD.index = set_index;
  2092.    DD.color = set_color;
  2093.    DD.clear_index = clear_index;
  2094.    DD.clear_color = clear_color;
  2095.    DD.index_mask = index_mask;
  2096.    DD.color_mask = color_mask;
  2097.    DD.logicop = logicop;
  2098.    DD.dither = dither;
  2099.    DD.get_points_func = xmesa_get_points_func;
  2100.    DD.get_line_func = xmesa_get_line_func;
  2101.    DD.get_polygon_func = xmesa_get_polygon_func;
  2102.  
  2103.    /*
  2104.     * These drawing functions depend on current color buffer config:
  2105.     */
  2106.    if (XMesa->buffer!=XIMAGE) {
  2107.       /* Writing to window or back pixmap */
  2108.       DD.clear = clear_pixmap;
  2109.       switch (XMesa->pixelformat) {
  2110.      case PF_INDEX:
  2111.         DD.write_index_span       = write_span_index_pixmap;
  2112.         DD.write_monoindex_span   = write_span_mono_pixmap;
  2113.         DD.write_index_pixels     = write_pixels_index_pixmap;
  2114.         DD.write_monoindex_pixels = write_pixels_mono_pixmap;
  2115.         break;
  2116.      case PF_TRUECOLOR:
  2117.         /* Generic RGB */
  2118.         DD.write_color_span       = write_span_TRUECOLOR_pixmap;
  2119.         DD.write_monocolor_span   = write_span_mono_pixmap;
  2120.         DD.write_color_pixels     = write_pixels_TRUECOLOR_pixmap;
  2121.         DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2122.         break;
  2123.      case PF_8A8B8G8R:
  2124.         DD.write_color_span       = write_span_8A8B8G8R_pixmap;
  2125.         DD.write_monocolor_span   = write_span_mono_pixmap;
  2126.         DD.write_color_pixels     = write_pixels_8A8B8G8R_pixmap;
  2127.         DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2128.         break;
  2129.      case PF_DITHER:
  2130.         DD.write_color_span       = write_span_DITHER_pixmap;
  2131.         DD.write_monocolor_span   = write_span_mono_DITHER_pixmap;
  2132.         DD.write_color_pixels     = write_pixels_DITHER_pixmap;
  2133.         DD.write_monocolor_pixels = write_pixels_mono_DITHER_pixmap;
  2134.         break;
  2135.      case PF_1BIT:
  2136.         DD.write_color_span       = write_span_1BIT_pixmap;
  2137.         DD.write_monocolor_span   = write_span_mono_pixmap;
  2138.         DD.write_color_pixels     = write_pixels_1BIT_pixmap;
  2139.         DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2140.         break;
  2141.          case PF_HPCR:
  2142.             DD.write_color_span       = write_span_HPCR_pixmap;
  2143.             DD.write_monocolor_span   = write_span_mono_pixmap;
  2144.             DD.write_color_pixels     = write_pixels_HPCR_pixmap;
  2145.             DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2146.             break;
  2147.          case PF_LOOKUP:
  2148.             DD.write_color_span       = write_span_LOOKUP_pixmap;
  2149.             DD.write_monocolor_span   = write_span_mono_pixmap;
  2150.             DD.write_color_pixels     = write_pixels_HPCR_pixmap;
  2151.             DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2152.             break;
  2153.          case PF_GRAYSCALE:
  2154.             DD.write_color_span       = write_span_GRAYSCALE_pixmap;
  2155.             DD.write_monocolor_span   = write_span_mono_pixmap;
  2156.             DD.write_color_pixels     = write_pixels_GRAYSCALE_pixmap;
  2157.             DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2158.             break;
  2159.      default:
  2160.         die("Bad pixel format in xmesa_setup_DD_pointers (1)");
  2161.       }
  2162.    }
  2163.    else if (XMesa->buffer==XIMAGE) {
  2164.       /* Writing to back XImage */
  2165.       switch (XMesa->backimage->bits_per_pixel) {
  2166.          case 8:
  2167.             DD.clear = clear_8bit_ximage;
  2168.             break;
  2169.          case 16:
  2170.             DD.clear = clear_16bit_ximage;
  2171.             break;
  2172.          case 32:
  2173.             DD.clear = clear_32bit_ximage;
  2174.             break;
  2175.          default:
  2176.             DD.clear = clear_nbit_ximage;
  2177.             break;
  2178.       }
  2179.       switch (XMesa->pixelformat) {
  2180.      case PF_INDEX:
  2181.         DD.write_index_span       = write_span_index_ximage;
  2182.         DD.write_monoindex_span   = write_span_mono_ximage;
  2183.         DD.write_index_pixels     = write_pixels_index_ximage;
  2184.         DD.write_monoindex_pixels = write_pixels_mono_ximage;
  2185.         break;
  2186.      case PF_TRUECOLOR:
  2187.         /* Generic RGB */
  2188.         DD.write_color_span       = write_span_TRUECOLOR_ximage;
  2189.         DD.write_monocolor_span   = write_span_mono_ximage;
  2190.         DD.write_color_pixels     = write_pixels_TRUECOLOR_ximage;
  2191.         DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2192.         break;
  2193.      case PF_8A8B8G8R:
  2194.         DD.write_color_span       = write_span_8A8B8G8R_ximage;
  2195.         DD.write_monocolor_span   = write_span_mono_8A8B8G8R_ximage;
  2196.         DD.write_color_pixels     = write_pixels_8A8B8G8R_ximage;
  2197.         DD.write_monocolor_pixels = write_pixels_mono_8A8B8G8R_ximage;
  2198.         break;
  2199.      case PF_DITHER:
  2200.         if (XMesa->depth==8) {
  2201.            DD.write_color_span       = write_span_DITHER8_ximage;
  2202.            DD.write_monocolor_span   = write_span_mono_DITHER8_ximage;
  2203.            DD.write_color_pixels     = write_pixels_DITHER8_ximage;
  2204.            DD.write_monocolor_pixels = write_pixels_mono_DITHER8_ximage;
  2205.         }
  2206.         else {
  2207.            DD.write_color_span       = write_span_DITHER_ximage;
  2208.            DD.write_monocolor_span   = write_span_mono_DITHER_ximage;
  2209.            DD.write_color_pixels     = write_pixels_DITHER_ximage;
  2210.            DD.write_monocolor_pixels = write_pixels_mono_DITHER_ximage;
  2211.         }
  2212.         break;
  2213.      case PF_1BIT:
  2214.         DD.write_color_span       = write_span_1BIT_ximage;
  2215.         DD.write_monocolor_span   = write_span_mono_ximage;
  2216.         DD.write_color_pixels     = write_pixels_1BIT_ximage;
  2217.         DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2218.         break;
  2219.          case PF_HPCR:
  2220.             DD.write_color_span       = write_span_HPCR_ximage;
  2221.             DD.write_monocolor_span   = write_span_mono_HPCR_ximage;
  2222.             DD.write_color_pixels     = write_pixels_HPCR_ximage;
  2223.             DD.write_monocolor_pixels = write_pixels_mono_HPCR_ximage;
  2224.             break;
  2225.          case PF_LOOKUP:
  2226.             DD.write_color_span       = write_span_LOOKUP_ximage;
  2227.             DD.write_monocolor_span   = write_span_mono_ximage;
  2228.             DD.write_color_pixels     = write_pixels_LOOKUP_ximage;
  2229.             DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2230.             break;
  2231.          case PF_GRAYSCALE:
  2232.         if (XMesa->depth==8) {
  2233.            DD.write_color_span       = write_span_GRAYSCALE8_ximage;
  2234.            DD.write_monocolor_span   = write_span_mono_GRAYSCALE8_ximage;
  2235.            DD.write_color_pixels     = write_pixels_GRAYSCALE8_ximage;
  2236.            DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2237.         }
  2238.         else {
  2239.            DD.write_color_span       = write_span_GRAYSCALE_ximage;
  2240.            DD.write_monocolor_span   = write_span_mono_ximage;
  2241.            DD.write_color_pixels     = write_pixels_GRAYSCALE_ximage;
  2242.            DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2243.         }
  2244.         break;
  2245.      default:
  2246.         die("Bad pixel format in xmesa_setup_DD_pointers (2)");
  2247.       }
  2248.    }
  2249.  
  2250.    /* Pixel/span reading functions: */
  2251.    DD.read_index_span = read_index_span;
  2252.    DD.read_color_span = read_color_span;
  2253.    DD.read_index_pixels = read_index_pixels;
  2254.    DD.read_color_pixels = read_color_pixels;
  2255. }
  2256.